package com.tsingtao.arch.rule;

import static com.societegenerale.commons.plugin.utils.ArchUtils.importAllClassesInPackage;
import static com.tngtech.archunit.base.DescribedPredicate.not;
import static com.tngtech.archunit.core.domain.JavaClass.Predicates.resideInAPackage;
import static com.tngtech.archunit.core.domain.JavaClass.Predicates.simpleName;
import static com.tngtech.archunit.core.domain.JavaClass.Predicates.simpleNameEndingWith;
import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.classes;

import com.societegenerale.commons.plugin.rules.ArchRuleTest;
import com.societegenerale.commons.plugin.service.ScopePathProvider;
import com.tngtech.archunit.base.DescribedPredicate;
import com.tngtech.archunit.core.domain.JavaClass;
import java.util.Collection;

/**
 * MQ 规则检查
 */
public class MqRulesTest implements ArchRuleTest {

  public static final DescribedPredicate<JavaClass> CONSUMER = resideInAPackage("..mq..")
      .and(resideInAPackage("..consumer.."));

  public static final DescribedPredicate<JavaClass> PRODUCER = resideInAPackage("..mq..")
      .and(resideInAPackage("..producer.."));

  @Override
  public void execute(String packagePath, ScopePathProvider scopePathProvider, Collection<String> excludedPaths) {
    classes().that(CONSUMER).or(simpleNameEndingWith("Consumer")).should()
        .haveSimpleNameEndingWith("Consumer").andShould()
        .resideInAPackage("..mq..").andShould()
        .resideInAPackage("..consumer..").andShould()
        .beAnnotatedWith("org.springframework.stereotype.Component")
        .check(importAllClassesInPackage(scopePathProvider.getMainClassesPath(), packagePath, excludedPaths));

    classes().that(PRODUCER)
        .or(simpleNameEndingWith("Producer").and(not(simpleName("AbstractBusProducer")))).should()
        .haveSimpleNameEndingWith("Producer").andShould()
        .resideInAPackage("..mq..").andShould()
        .resideInAPackage("..producer..").andShould()
        .beAnnotatedWith("org.springframework.stereotype.Component")
        .check(importAllClassesInPackage(scopePathProvider.getMainClassesPath(), packagePath, excludedPaths));
  }

}